home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
machack
/
Hacks96
/
BootingGallery.sit
/
Booting Gallery
/
Booting Gallery (source)
/
iconhack Folder
/
Blitter.jbx.c
< prev
next >
Wrap
Text File
|
1996-06-22
|
11KB
|
378 lines
#define using_MacTraps 1
#include <Traps.h>
#include "Blitter.h"
typedef struct {
long Icon[32];
long IconMask[32];
} ICONList, *ICONListPtr;
static pascal void INITDraw1Bit(ICONListPtr iconPtr);
static pascal void INITDrawCQD(CIconHandle);
static pascal void INITDrawXBit(void *icl_Ptr, short iclDepth, ICONListPtr iconPtr);
Handle icl8, icl4, icn;
short haveICN, have4, have8;
short myV, myH, curOffset;
Rect curRect;
short blitEnabled;
CTabHandle gClutThing4; // (CTabHandle) RGetResource('clut', iclDepth);
CTabHandle gClutThing8; // (CTabHandle) RGetResource('clut', iclDepth);
THz BlitZone;
static void (*UndoBlitProc)(void);
void Blit(short iconID) {
Handle h;
while (curOffset != 0) BackBlit();
UndoBlitProc = 0;
blitEnabled = 0;
if (gClutThing4 == 0) {
gClutThing4 = (CTabHandle) RGetResource('clut', 4);
gClutThing8 = (CTabHandle) RGetResource('clut', 8);
}
haveICN = have4 = have8 = 0;
if (!icl8) {
icl8 = NewHandleSysClear(1024); // 32 x 32 x 8 bits
HLock(icl8);
}
if (!icl4) {
icl4 = NewHandleSysClear(512); // 32 x 32 x 4 bits
HLock(icl4);
}
if (!icn) {
icn = NewHandleSysClear(256); // 32 x 32 x 1 bits x 2
HLock(icn);
}
if (0 != (h = Get1Resource('ICN#', iconID))) {
BlockMove(*h, *icn, 256);
haveICN = 1;
}
if (0 != (h = Get1Resource('icl4', iconID))) {
BlockMove(*h, *icl4, 512);
have4 = 1;
}
if (0 != (h = Get1Resource('icl8', iconID))) {
BlockMove(*h, *icl8, 1024);
have8 = 1;
}
curOffset = -1;
blitEnabled = 1;
}
void BackBlit(void) {
THz oldZone;
short oldMemError;
char oldNameByte;
if (!blitEnabled) return;
if (!haveICN) {
curOffset = 0;
return;
}
blitEnabled = 0;
oldMemError = *(short *)0x220;
oldZone = GetZone();
SetZone(BlitZone);
if (curOffset == -1) {
curOffset = *(short *)0xC20 - myH - 40;
if (curOffset < 0) curOffset = 0;
}
if (curOffset > 0) {
curOffset -= 8;
if (curOffset < 0) curOffset = 0;
}
oldNameByte = *(char *)0x910;
*(char *)0x910 = 1;
if (UndoBlitProc) {
UndoBlitProc();
UndoBlitProc = 0;
}
if (have8) {
INITDrawXBit((void *)*icl8, 8, (void *)*icn);
} else if (have4) {
INITDrawXBit((void *)*icl4, 4, (void *)*icn);
} else {
INITDraw1Bit((void *)*icn);
}
*(char *)0x910 = oldNameByte;
SetZone(oldZone);
*(short *)0x220 = oldMemError;
if (curOffset != 0) blitEnabled = 1;
}
enum {
firstX = 8, /* X coordinate of first icon to be drawn */
bottomEdge = 8+32, /* this far from bottom of screen */
iconWidth = 32, /* size of icon (square normally) */
defaultMoveX = 40, /* x default amount to move icons */
defaultMoveY = 40, /* y icon line height */
checksumConst = 0x1021, /* constant used for computing checksum */
iconRowBytes = 32/8, /* 32/8 bits */
hasCQDBit = 6 /* this bit in ROM85 is cleared if Color QuickDraw is available */
};
static long saveA5;
static long localA5;
static Rect srcRect = {0,0,32,32}; /* for copybits */
static Rect destRect= {0,0,32,32};
static BitMap myBitMap = {
0, /* address */
iconRowBytes, /* rowBytes */
0,0,32,32 /* Rect */
};
static BitMap myMaskMap = {
0, /* address */
iconRowBytes, /* rowBytes */
0,0,32,32 /* Rect */
};
static GrafPort myPort;
/***************************************************************************************\
| |
| Initializes the world and sets up the drawing rectangle |
| |
\***************************************************************************************/
static asm void INITInitSimple(void) {
// CurrentA5 = 0x904
move.l 0x904,saveA5 // PM 10/6 save host A5
lea localA5,a5 // PM7/21
move.l a5,0x904
pea qd.thePort // PM 10/6 use a5 reference instead of a6
_InitGraf // fixes color bug as per DA@ICOM
pea myPort
_OpenPort
rts
}
static asm void INITInit(void) {
// CurrentA5 = 0x904
move.l 0x904,saveA5 // PM 10/6 save host A5
lea localA5,a5 // PM7/21
move.l a5,0x904
pea qd.thePort // PM 10/6 use a5 reference instead of a6
_InitGraf // fixes color bug as per DA@ICOM
pea myPort
_OpenPort
move.w myV,d0 // get my v var
bne.s @ScratchVOK // checks, so go on test my h var
move.w myPort.portBits.bounds.bottom,d0 // else initialize as first time
sub.w #160,d0
sub.w #bottomEdge,d0
move d0,myV
@ScratchVOK:
move.w myH,d0 // get my h var
bne.s @ScratchHOK // checks, so go on
move #firstX,myH // else initialize as first time
@ScratchHOK:
move.l myV,d0 // trickery - high word is V, lo word is H.
move.w d0,d1 // get future position
add.w #iconWidth,d1 // compute future rect right
cmp.w myPort.portBits.bounds.right,d1 // compare to main screen right
blt.s @DontChangeLine // smaller - do nothing
move.w myV,d0 // decrement Y value
subi.w #defaultMoveY,d0
move.w d0,myV
move.w #firstX,myH // set X to initial value
move.l myV,d0
@DontChangeLine:
lea destRect,a0
move.l d0,(a0)+
move.l d0,(a0)
rts
}
/***************************************************************************************\
| |
| Based on the mask, advances the icon drawing position and adjusts destRect |
| |
\***************************************************************************************/
static asm void MaskAdjust(void) {
// if (curOffset > 0) return;
lea myMaskMap,a0
move.l (a0)+,a1 // baseAddr
move.w (a0)+,d0 // rowBytes
move.w 4(a0),d1 // bottom
move.w 6(a0),d2 // right
sub.w (a0)+,d1 // top - d1 now has height.
sub.w (a0)+,d2 // left - d2 now has width.
add.w d1, destRect.bottom
add.w d2, destRect.right
tst.w curOffset
bgt.s @out
add.w d2,myH // assume the icon is properly done,
addq.w #8,myH
@out:
rts
}
/***************************************************************************************\
| |
| Cleans up the work done by INITInit and advances the icon drawing position |
| |
\***************************************************************************************/
static asm void INITCleanup(void) {
pea myPort // *** (DBA) I think that QuickDraw leaves handles around.
_ClosePort // *** (DBA) Too bad we can't get rid of them...
move.l saveA5,a5 // PM 10/6 restore host A5
move.l a5,0x904
rts
}
uchar savedBits[1024];
long AllOnes[32] = {
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1
};
Rect restoreSrc, restoreDst;
short restoreDepth;
/***************************************************************************************\
| |
| display the ICN# pointed to by iconPtr and move the pen horizontally by moveX |
| pass a -1 in moveX to move the standard amount, moveX should be 40 for most ICN#'s |
| |
| PROCEDURE INITDraw1Bit(iconPtr: ICONListPtr); EXTERNAL |
| |
| pascal void INITDraw1Bit(ICONListPtr iconPtr); |
| |
\***************************************************************************************/
static pascal void INITDraw1Bit(ICONListPtr iconPtr) {
INITInit(); /* initialize for drawing. */
myBitMap.baseAddr = (void *)iconPtr->Icon;
myMaskMap.baseAddr = (void *)iconPtr->IconMask;
MaskAdjust();
destRect.left += curOffset;
destRect.right += curOffset;
CopyMask(&myBitMap, &myMaskMap, &myPort.portBits, &srcRect, &srcRect, &destRect);
INITCleanup(); /* cleanup */
}
/***************************************************************************************\
| |
| display the Icl pointed to by iclPtr and move the pen horizontally by moveX |
| pass a -1 in moveX to move the standard amount, moveX should be 40 for most ICN#'s |
| |
| PROCEDURE INITDrawXBit(iclPtr: icl_Ptr; iclDepth: Integer; |
| iconPtr: ICONListPtr); EXTERNAL; |
| |
| pascal void INITDrawXBit(icl_Ptr, iclDepth, moveX) |
| icl_Ptr *iclPtr; |
| short iclDepth; |
| ICONList *iconPtr; |
| extern; |
| |
\***************************************************************************************/
static void UndoXBit(void) {
PixMapHandle pmh;
register PixMapPtr pmp;
if (0 != (pmh = NewPixMap())) {
INITInitSimple();
HLock((Handle) pmh);
pmp = *pmh;
DisposeHandle((Handle) pmp->pmTable);
if (restoreDepth == 4) {
pmp->pmTable = gClutThing4; // (CTabHandle) RGetResource('clut', iclDepth);
} else {
pmp->pmTable = gClutThing8; // (CTabHandle) RGetResource('clut', iclDepth);
}
pmp->baseAddr = (void *)&savedBits;
pmp->rowBytes = 0x8000 | (restoreDepth * iconRowBytes);
pmp->bounds = restoreSrc;
pmp->pixelType = chunky;
pmp->pixelSize = restoreDepth;
pmp->cmpCount = 1;
pmp->cmpSize = restoreDepth;
CopyBits((BitMap *)pmp, &myPort.portBits, &restoreSrc, &restoreDst, srcCopy, 0);
pmp->pmTable = (void *)NewHandle(0);
DisposPixMap(pmh);
INITCleanup(); /* cleanup, advance icon location */
}
}
static pascal void INITDrawXBit(void *icl_Ptr, register short iclDepth, ICONListPtr iconPtr) {
PixMapHandle pmh;
register PixMapPtr pmp;
if (!(pmh = NewPixMap())) {
INITDraw1Bit(iconPtr);
} else {
INITInit(); /* initialize for drawing */
HLock((Handle) pmh);
pmp = *pmh;
DisposeHandle((Handle) pmp->pmTable);
if (iclDepth == 4) {
pmp->pmTable = gClutThing4; // (CTabHandle) RGetResource('clut', iclDepth);
} else {
pmp->pmTable = gClutThing8; // (CTabHandle) RGetResource('clut', iclDepth);
}
pmp->baseAddr = icl_Ptr;
pmp->rowBytes = 0x8000 | (iclDepth * iconRowBytes);
pmp->bounds = srcRect;
pmp->pixelType = chunky;
pmp->pixelSize = iclDepth;
pmp->cmpCount = 1;
pmp->cmpSize = iclDepth;
myMaskMap.baseAddr = (void *)iconPtr->IconMask;
MaskAdjust();
destRect.left += curOffset;
destRect.right += curOffset;
restoreSrc = srcRect;
restoreDst = destRect;
restoreDepth = iclDepth;
pmp->baseAddr = (void *)&savedBits;
CopyBits(&myPort.portBits, (BitMap *)pmp, &destRect, &srcRect, srcCopy, 0);
UndoBlitProc = &UndoXBit;
pmp->baseAddr = icl_Ptr;
myMaskMap.baseAddr = (void *)iconPtr->IconMask;
CopyMask((BitMap *)pmp, &myMaskMap, &myPort.portBits, &srcRect, &srcRect, &destRect);
pmp->pmTable = (void *)NewHandle(0);
DisposPixMap(pmh);
INITCleanup(); /* cleanup, advance icon location */
}
}